/*  
*	Passing arrays to and from functions safely and securely	*
*	HieuMT														*
*	Date: 2014/05/08											*
*/  

// (1) Passing arrays to functions as arguments

#include <iostream>
#include <math.h>
#include <vector>
#include <deque>
#include <list>
#include "Hieumt_vs3_struct.h"

using namespace std;

int i = 0;
const int DATA_SIZE = 10;
const int DATA_SIZE_CHAR = 26;
const int LENGTH2 = 20;
int data_array[DATA_SIZE];
char data_array_char[DATA_SIZE_CHAR];

void printArray(int data[DATA_SIZE]);
void generateData(int data[DATA_SIZE], int k);
void generateArray(int *&array, int length);
void generateArrayChar(char *array, int length);

template <class ForwardIteType>
void printArray2(ForwardIteType begin, ForwardIteType end);

template <class ContainerType>
void printArray3(const ContainerType& container);

void readScores(std::vector<int>& container);

void testRefPointer(int * const p, int a);

float convertStringToFloat(char[]);

int main() {

	cout<<"**************ARRAY****************\n\n";
//	Part 1: Passing arrays to functions as arguments
	cout<<"Part 1: \n";
//	Method 1 
	generateData(data_array, 3);
	printArray(data_array);

//	Method 2 
	generateData(data_array, 200);
	std::vector<int>v_data(data_array, data_array + DATA_SIZE);
	printArray2(v_data.begin(), v_data.end());
	generateData(data_array, 15);
	std::list<int>list_data(data_array, data_array + DATA_SIZE);
	printArray2(list_data.begin(), list_data.end());
	generateData(data_array, 20);
	std::deque<int>deque_data(data_array, data_array + DATA_SIZE);
	printArray2(deque_data.begin(), deque_data.end());

//	Method 3
	printArray3(v_data);
	printArray3(list_data);
	printArray3(deque_data);

//	Part 2: Get the arrays from functions
	cout<<"\nPart 2: \n";
//	Method 1
	int* data_array2;
	generateArray(data_array2, LENGTH2);
	printArray(data_array2);
	delete []data_array2;

//	Method 2
	std::vector<int> scores;
	readScores(scores);
	printArray2(scores.begin(), scores.end());
	cout<<endl<<endl;

//	Struct
	cout<<"**************STRUCT****************\n\n";
	Str_Hieumt hmt;
//	hmt.name = new char[20];
//	strcpy(hmt.name, "Mai Trung Hieu");
	hmt.name = "mai trung hieu";

	hmt.age = 24;

	cout<<hmt.name<<" "<<hmt.age<<endl<<endl;
	cout<<"**********test ref pointer*********\n\n";

	int nPref1 = 10;
	int nPref2 = 20;
	int *pref = &nPref1;
	testRefPointer(pref, nPref2);
	cout<<"*pref: "<<*pref<<endl<<endl;

	cout<<"**************Convert char* char array string ****************\n\n";
//	generateArrayChar(data_array_char, DATA_SIZE_CHAR);
//	cout<<data_array_char<<endl;
	char inputstr[] = "123.45";
	string s(inputstr);
	float result = convertStringToFloat("7.50002");
	cout<<"result = "<<result<<endl;
	printf("result convert = %f ",result);

	cout<<endl;

	return 0;
}



void generateData(int data[DATA_SIZE], int k) {	

	for(i = 0; i < DATA_SIZE; i++) {
		data[i] = rand()%k;
	}

}

void generateArray(int *&array, int length) {
	int *p = new int[length];
	for(i = 0; i < length; i++) {
		p[i] = rand()%(length/3);
	}	
	array = p;
}

void generateArrayChar(char *array, int length) {
	char *p = new char[length];
	for(i = 0; i < length; i++) {
		p[i] = (char)(i + 65);
//		cout<<p[i]<<" ";
	}	
	array = p;
}

void printArray(int data[DATA_SIZE]) {

	for(int i = 0; i < DATA_SIZE; i++) {
		cout<<data[i]<<" ";
	}

	cout<<endl;
}

//void printArrayChar(char data[DATA_SIZE_CHAR]) {
//
//	for(int i = 0; i < DATA_SIZE_CHAR; i++) {
//		cout<<data[i]<<" ";
//	}
//
//	cout<<endl;
//}

template <class ForwardIteType>
void printArray2(ForwardIteType begin, ForwardIteType end) {

	while(begin != end) {
		cout<<*begin<<" ";
		begin++;
	}

	cout<<endl;
}

template <class ContainerType>
void printArray3(const ContainerType& container) {

	ContainerType::const_iterator current(container.begin());
	ContainerType::const_iterator end(container.end());

	for(; current != end; current++) {
		cout<<*current<<" ";
	}

	cout<<endl;
}

void readScores(std::vector<int>& container)
{
    int temp = 0;
    while( temp <= 10)
    {	
        container.push_back(temp+1);
		temp += 1;
    }
}

void testRefPointer( int * const p, int a) {
	*p = 20;
//	p = &a;
}

float convertStringToFloat(char inputstr[]) {
float result= 0.0f;
   size_t len = sizeof(inputstr)-1;
   size_t dotpos = 0;
   for (size_t n = 0; n < len; n++)
   {
     if (inputstr[n] == '.')
     {
       dotpos = len - n  - 1;
     }
     else
     {
       result = result * 10.0f + (inputstr[n]-'0');
     }
   }
   while ( dotpos--)
   {
     result /= 10.0f;
   }

   return result;
}